
// 这段。。。
// fileUtils  对文件的读写操作


const AndroidVoiceRecorder = "org/cocos2dx/javascript/VoiceRecorder";
const AndroidVoicePlayer = "org/cocos2dx/javascript/VoicePlayer"
const IosClassName = "VoiceSDK";

class VoiceNative {

    _voiceMediaPath = null;

    radix = 0;
    base = 0;
    encodermap = {};
    decodermap = {};


    init() {
        this.radix = 12;
        this.base = 128 - this.radix;
        if (cc.sys.isNative) {
            this._voiceMediaPath = jsb.fileUtils.getWritablePath() + "/voicemsgs/";
            this.setStorageDir(this._voiceMediaPath);
        }

        for (var i = 0; i < 256; ++i) {
            var code = null;
            var v = i + 1;
            if (v >= this.base) {
                code = this.crypto(v);
            } else {
                code = String.fromCharCode(v);
            }

            this.encodermap[i] = code;
            this.decodermap[code] = i;
        }
    }

    // TOUCH_START
    prepare(filename) {
        if (!cc.sys.isNative) {
            return;
        }
        //暂停现在正在播放的所有音频
        cc.audioEngine.pauseAll();
        // 删除之前
        this.clearCache(filename);
        if (cc.sys.isNative) {
            if (cc.sys.os == cc.sys.OS_ANDROID) {
                jsb.reflection.callStaticMethod(AndroidVoiceRecorder, "prepare", "(Ljava/lang/String;)V", filename);
            }
            else if (cc.sys.os == cc.sys.OS_IOS) {
                jsb.reflection.callStaticMethod(IosClassName, "prepareRecord:", filename);
            }
        }
    }
    //TOUCH_END
    release() {
        if (!cc.sys.isNative) {
            return;
        }
        cc.audioEngine.resumeAll();
        if (cc.sys.isNative) {
            if (cc.sys.os == cc.sys.OS_ANDROID) {
                jsb.reflection.callStaticMethod(AndroidVoiceRecorder, "release", "()V");
            }
            else if (cc.sys.os == cc.sys.OS_IOS) {
                jsb.reflection.callStaticMethod(IosClassName, "finishRecord");
            }
        }
    }
    // TOUCH_CANCEL // 录音时间小于 1 秒
    cancel() {
        if (!cc.sys.isNative) {
            return;
        }
        cc.audioEngine.resumeAll();
        if (cc.sys.isNative) {
            if (cc.sys.os == cc.sys.OS_ANDROID) {
                jsb.reflection.callStaticMethod(AndroidVoiceRecorder, "cancel", "()V");
            }
            else if (cc.sys.os == cc.sys.OS_IOS) {
                jsb.reflection.callStaticMethod(IosClassName, "cancelRecord");
            }
        }
    }
    //
    writeVoice(filename, voiceData) {
        if (!cc.sys.isNative) {
            return;
        }
        if (voiceData && voiceData.length > 0) {
            // var fileData = decode(voiceData);
            var url = this._voiceMediaPath + filename;
            this.clearCache(filename);
            jsb.fileUtils.writeDataToFile(voiceData, url);
        }
    }

    clearCache(filename) {
        if (cc.sys.isNative) {
            var url = this._voiceMediaPath + filename;
            //console.log("check file:" + url);
            if (jsb.fileUtils.isFileExist(url)) {
                //console.log("remove:" + url);
                jsb.fileUtils.removeFile(url);
            }
            if (jsb.fileUtils.isFileExist(url + ".wav")) {
                //console.log("remove:" + url + ".wav");
                jsb.fileUtils.removeFile(url + ".wav");
            }
        }
    }

    play(filename) {
        if (!cc.sys.isNative) {
            return;
        }
        cc.audioEngine.pauseAll();
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod(AndroidVoicePlayer, "play", "(Ljava/lang/String;)V", filename);
        }
        else if (cc.sys.os == cc.sys.OS_IOS) {
            jsb.reflection.callStaticMethod(IosClassName, "play:", filename);
        }
        else {
        }
    }

    // 读取用来发送;
    getVoiceData(filename) {
        if (cc.sys.isNative) {
            var url = this._voiceMediaPath + filename;
            console.log("getVoiceData:" + url);
            // 读取二进制文件 获取文件数据           
            var fileData = jsb.fileUtils.getDataFromFile(url);
            if (fileData) {
                // var content = encode(fileData);
                var content = fileData;
                return content;
            }
        }
        return "";
    }

    getDataString(data) {
        var content = this.encode(data);
        return content;
    }

    setStorageDir(dir) {
        if (!cc.sys.isNative) {
            return;
        }
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod(AndroidVoiceRecorder, "setStorageDir", "(Ljava/lang/String;)V", dir);
        } else if (cc.sys.os == cc.sys.OS_IOS) {
            jsb.reflection.callStaticMethod(IosClassName, "setStorageDir:", dir);
            if (!jsb.fileUtils.isDirectoryExist(dir)) {
                jsb.fileUtils.createDirectory(dir);
            }
        }
    }

    crypto(value) {
        value -= this.base;
        var h = Math.floor(value / this.radix) + this.base;
        var l = value % this.radix + this.base;
        return String.fromCharCode(h) + String.fromCharCode(l);
    }

    // src_data => dst_data( 长度 + 数据)
    encode(data) {
        var content = "";
        var len = data.length;

        cc.log('encode, len=' + len + ', data=' + data);
        var a = (len >> 24) & 0xff;
        var b = (len >> 16) & 0xff;
        var c = (len >> 8) & 0xff;
        var d = len & 0xff;
        content += this.encodermap[a];
        content += this.encodermap[b];
        content += this.encodermap[c];
        content += this.encodermap[d];
        for (var i = 0; i < data.length; ++i) {
            content += this.encodermap[data[i]];
        }
        return content;
    }

    getCode(content, index) {
        var c = content.charCodeAt(index);
        if (c >= this.base) {
            c = content.charAt(index) + content.charAt(index + 1);
        } else {
            c = content.charAt(index);
        }
        return c;
    }

    decode(content) {
        var index = 0;
        var len = 0;
        for (var i = 0; i < 4; ++i) {
            var c = this.getCode(content, index);
            index += c.length;
            var v = this.decodermap[c];
            len |= v << (3 - i) * 8;
        }

        var newData = new Uint8Array(len);
        var cnt = 0;
        while (index < content.length) {
            var c = this.getCode(content, index);
            index += c.length;
            newData[cnt] = this.decodermap[c];
            cnt++;
        }
        return newData;
    }

}
export let voiceNative: VoiceNative = new VoiceNative();

